#include <iostream>
#include "Texture2D.h"
#include "stb_image.h"

namespace lazy {
    Texture2D::~Texture2D() {
        glDeleteTextures(1, &m_TextureID);
    }

    Ref<Texture2D> Texture2D::LoadFromFile(const std::filesystem::path &filePath) {
        auto texture2D = CreateRef<Texture2D>();
        GLuint textureID;
        int width, height, channels;
        GLenum format = GL_RGB;
        stbi_set_flip_vertically_on_load(true);
        unsigned char *data = stbi_load(filePath.u8string().c_str(), &width, &height, &channels, 0);
        if (data) {
            switch (channels) {
                case 1: {
                    format = GL_ALPHA;
                    break;
                }
                case 3: {
                    format = GL_RGB;
                    break;
                }
                case 4: {
                    format = GL_RGBA;
                    break;
                }
            }
        }
        glGenTextures(1, &textureID);
        glBindTexture(GL_TEXTURE_2D, textureID);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, format, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        texture2D->m_TextureID = textureID;
        texture2D->m_Format = format;
        texture2D->m_Width = width;
        texture2D->m_Height = height;

        stbi_image_free(data);
        return texture2D;
    }

    void Texture2D::Bind(uint32_t slot) {
        glBindTextureUnit(slot, m_TextureID);
        // glBindTexture(GL_TEXTURE_2D, m_TextureID);
    }

    bool Texture2D::operator==(const Texture2D &other) {
        return m_TextureID == other.m_TextureID;
    }

    GLuint Texture2D::GetTextureID() const {
        return m_TextureID;
    }

} // lazy